/**********************************************************************************************************************
 * @file    nmea_gsv.c
 * @author  Queclink Jason.huang
 * @date    2019-01-02
 * @brief   NMEA-GSV frame source.
 *
 * Copyright (C) 2018 Queclink Wireless Solutions (ShenZhen) Co., Ltd. All Rights Reserved.
 *
 * @attention
 *
 * @usage
 *
 *********************************************************************************************************************/

/* includes ---------------------------------------------------------------------------------------------------------*/
#include "qlcommon.h"
#include <stdlib.h>
#include <string.h>
#include "nmea.h"
#include <gnss_info_process.h>

/*
 * @brief  GSV消息解析
 * @note
 * @param  argc: [I], 消息分割后字符串数量
 *         argv: [I], 字符串地址列表
 * @retval none
 */
void nmea_gsv_parse(int argc, char *argv[])
{
    uint8_t total_item;                 /* 语句总数 */
    uint8_t item_num;                   /* 语句编号 */
    uint8_t num_block;                  /* 卫星信息块数量 */
    uint8_t num_view;                   /* 可见卫星总数 */

    static uint8_t sats_cnt;            /* 卫星计数 */
    static struct sat_info_single *sats_info = NULL;    /* 卫星信息缓存 */

    uint8_t gnss_id;                    /* GNSS ID, 区分不同的卫星系统 */
    uint8_t signal_id;                  /* 信号 ID */
    uint8_t sat_index;                  /* 卫星索引 */

    nmea_protocol_parse_t *nmea_ptr = NULL;
    gnss_task_manage_t * gnss_manage = NULL;

    uint8_t     i = 0;

    gnss_manage = get_gnss_manage();
    nmea_ptr = get_nmea_manage_context();
    if (NULL == nmea_ptr)
        return;

    nmea_ptr->recv_nmea_msg |= GSV_MASK;
    if(!gnss_manage->gnss_info.is_uart_rx_ok)
        gnss_manage->gnss_info.is_uart_rx_ok = true;

    if (NULL == sats_info) {
        sats_info = qlmalloc(sizeof(struct sat_info_single));
        if (NULL == sats_info)
            return;
        memset(sats_info, 0, sizeof(struct sat_info_single));
        sats_cnt = 0;
    }

    /* 至少5个域 */
    if (argc < 5)
        return;

    /* 获取卫星系统信息 */
    switch(argv[0][2]) {
    case 'P':
        sat_index   = SV_GPS;
        gnss_id     = GNSS_ID_GPS;
        break;
    case 'L':
        sat_index   = SV_GLONASS;
        gnss_id     = GNSS_ID_GLONASS;
        break;
    case 'A':
        sat_index   = SV_GALILEO;
        gnss_id     = GNSS_ID_GALILEO;
        break;
    case 'B':
    case 'D':
        sat_index   = SV_BEIDOU;
        gnss_id     = GNSS_ID_BEIDOU;
        break;
    case 'Q':       /* BG95 "PQ" */
        if (argv[0][1] == 'P') {
            sat_index   = SV_BEIDOU;
            gnss_id     = GNSS_ID_BEIDOU;
        } else {
            return;
        }
        break;

    default:
        return;
    }

    num_block   = (argc - 5) >> 2;
    total_item  = (uint8_t)atoi(argv[1]);
    item_num    = (uint8_t)atoi(argv[2]);
    num_view    = (uint8_t)atoi(argv[3]);

    /* 获取信号 ID */
    if ((argc - num_block*4) == 6)
        signal_id = (uint8_t)atoi(argv[argc-2]);
    else
        signal_id = 0;

    i = 4;                                              /*卫星信息从字段4开始 */
    while(num_block--) {
        if (sats_cnt >= VIEW_SV_MAX)
            break;
        /* 信号值为0或为空则认为不是可见卫星， */
        if(0 < strlen(argv[i+3])) {
            sats_info->sat[sats_cnt].gnss_id    = gnss_id;                  /* 卫星系统 */
            sats_info->sat[sats_cnt].sv_id      = atoi(argv[i++]);          /* 卫星号  */
            sats_info->sat[sats_cnt].elevation  = atoi(argv[i++]);          /* 仰角 */
            sats_info->sat[sats_cnt].azimuth    = atoi(argv[i++]);          /* 方位角 */
            sats_info->sat[sats_cnt].signal_strength = atoi(argv[i++]);     /* 信号强度 */
            if (sats_info->sat[sats_cnt].signal_strength > 0)
                sats_cnt++;
        } else {
            i+=4;
        }
    }

    if (sats_cnt > num_view) {
        sats_cnt = 0;
        return;
    }

    if (total_item == item_num) {
        sats_info->count = sats_cnt;
        gnss_sat_info_update(sats_info, sat_index, signal_id);
        sats_cnt  = 0;
    }
}
